#include <stdio.h>
#include <algorithm>
#include <time.h>
#include <sstream>
#include "core/utils/string_helper.h"
#include "core/auth/shahmac1_signer.h"

namespace aliyun {

const string& string_ToLower(string& str) {
  transform(str.begin(), str.end(), str.begin(), ::tolower);
  return str;
}

int string_replace(string& str, const string& pattern, const string& replace) {
  int count = 0;
  const size_t pattern_length = pattern.length();
  if(pattern_length > 0) {
    const size_t replace_length = replace.length();
    for(size_t pos = str.find(pattern, 0); pos != std::string::npos; pos = str.find(pattern,pos + replace_length)) {
      str.replace(pos, pattern_length, replace);
      count++;
    }
  }
  return count;
}

void string_Split(const string& str, const string& delimit, std::vector<string>& array) {
  size_t start = 0;
  size_t index=str.find_first_of(delimit, start);
  while (std::string::npos != index) {
    array.push_back(str.substr(start, index-start));
    start = index+1;
    index = str.find_first_of(delimit, start);
  }
  if (index-start>0) {
    array.push_back(str.substr(start,index-start));
  }
}

string string_UrlEncode(const string& str) {
  if(str.empty()) {
    return "";
  }
  const size_t str_length = str.length();
  const char* pstr = str.c_str();
  char *buffer = new char[str_length*3+1];
  size_t buffer_length = 0;
  for(size_t i=0; i < str_length; i++) {
    char ch = pstr[i];
    if (('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ('0' <= ch && ch <= '9') ||
      ch == '.' || ch == '-' || ch == '_' || ch == '*') {
      buffer[buffer_length++] = ch;
    } else if (ch == ' ') {
      buffer[buffer_length++] = '+';
    } else {
      sprintf(&buffer[buffer_length], "%%%02X", (unsigned char)ch);
      buffer_length += 3;
    }
  }
  buffer[buffer_length] = '\0';
  return string(buffer);
}

string string_UrlPrecentEncode(const string& str) {
  string url_encode = string_UrlEncode(str);
  string_replace(url_encode, "+", "%20");
  string_replace(url_encode, "*", "%2A");
  string_replace(url_encode, "%7E", "~");
  return url_encode;
}

string string_Uuid(const string& key) {
  ShaHmac1Signer signer;
  char buffer[64];
  unsigned int currnet_time = time(NULL);
  sprintf(buffer, "%d%d", currnet_time, rand());
  return signer.SignString(buffer, key);
}

string string_ValueOfInt(int v) {
  std::ostringstream out_string_stream;
  out_string_stream << v;
  return string(out_string_stream.str());
}
string string_ValueOfInt64(int64 v) {
  char buf[64];
  const char *digit_chat="0123456789";
  char sign = '+';
  int i = 60;
  if(v == 0) {
	  return "0";
  }
  if(v < 0) {
	  sign = '-';
	  v = -v;
  }
  for(; i > 0 && v != 0; i--, v /= 10) {
	  buf[i] = digit_chat[v % 10];
  }
  if(sign == '-') {
	  buf[i--] = sign;
  }
  return string(&buf[i+1], 60-i);
}
string string_ValueOfBool(bool v) {
  return string(v ? "true" : "false");
}
string string_ValueOfFloat(float v) {
  std::ostringstream out_string_stream;
  out_string_stream << v;
  return string(out_string_stream.str());
}

} // namespace aliyun {

// end of file
